package upload

import (
	"context"
	v1 "devops-super/api/file/v1"
	"devops-super/internal/consts"
	"devops-super/internal/dao"
	"devops-super/internal/model/do"
	"devops-super/utility/util/minioUtil"
	"devops-super/utility/util/strUtil"
	"errors"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gtime"
	"os"
	"path"
	"time"
)

type OssUp struct{}

func (s *OssUp) Upload(ctx context.Context, file *ghttp.UploadFile) (result v1.UploadResponse, err error) {

	url, err := s.toOss(ctx, file)
	if err != nil {
		return
	}
	result = v1.UploadResponse{
		Size:     file.Size,
		Path:     url,
		FullPath: url,
		Name:     file.Filename,
		Type:     file.Header.Get("Content-type"),
	}

	return
}

func (s *OssUp) UploadBase64(ctx context.Context, base64Str string) (result v1.UploadResponse, err error) {
	confkey := minioUtil.UploadOssConfKey
	v, err := g.Cfg().Get(ctx, confkey)
	if err != nil {
		return
	}
	m := v.MapStrVar()
	var Bucket = m["bucket"].String()
	fileName := strUtil.RandomStr(10) + ".png"
	objectName := fmt.Sprintf("%04d%02d", time.Now().Year(), int(time.Now().Month())) + "/" +
		fmt.Sprintf("%02d", int(time.Now().Day())) + "/" + fileName
	size, err := minioUtil.PutBase64(ctx, confkey, Bucket, objectName, base64Str)
	if err != nil {
		return
	}
	obj := &minioUtil.FileObject{
		BucketName: Bucket,
		ObjectName: objectName,
		FileName:   fileName,
	}
	url, err := minioUtil.GetObjectUrl(ctx, confkey, obj, false)

	result = v1.UploadResponse{
		Size:     size,
		Path:     url,
		FullPath: url,
		Name:     fileName,
		Type:     "image/jpeg",
	}

	// 数据库记录文件信息
	dao.AppFiles.Ctx(ctx).Insert(do.AppFiles{
		ServerKey: confkey,
		Source:    consts.AppFileSource_OSS,
		Bucket:    Bucket,
		Path:      objectName,
		Size:      size,
		CreatedAt: gtime.Now(),
	})
	return
}

func (s *OssUp) toOss(ctx context.Context, f *ghttp.UploadFile) (url string, err error) {
	file, err := f.Open()
	if err != nil {
		return
	}
	defer file.Close()
	confkey := minioUtil.UploadOssConfKey

	yamlconf := minioUtil.GetMinioConfig(ctx, confkey)

	tmpDir := "/tmp/"
	filename1, err := f.Save(tmpDir)
	tmpFileFullPath := tmpDir + filename1

	if err != nil {
		return "", err
	}

	defer func(name string) {
		_ = os.Remove(name)
	}(tmpFileFullPath)

	var Bucket = yamlconf.Bucket

	if Bucket == "" {
		return
	}
	fileName := strUtil.RandomStr(10) + path.Ext(f.Filename)
	objectName := fmt.Sprintf("%04d%02d", time.Now().Year(), int(time.Now().Month())) + "/" +
		fmt.Sprintf("%02d", int(time.Now().Day())) + "/" + fileName
	obj := &minioUtil.FileObject{
		BucketName: Bucket,
		ObjectName: objectName,
		FilePath:   tmpFileFullPath,
		FileName:   fileName,
	}
	putRes, err := minioUtil.FPutObject(ctx, confkey, obj)
	if err != nil {
		return
	}
	if !putRes {
		err = errors.New("to oss fail")
		return
	}
	url, err = minioUtil.GetObjectUrl(ctx, confkey, obj, false)
	// 数据库记录文件信息
	dao.AppFiles.Ctx(ctx).Insert(do.AppFiles{
		ServerKey: confkey,
		Source:    consts.AppFileSource_OSS,
		Bucket:    Bucket,
		Path:      fileName,
		Size:      f.Size,
		CreatedAt: gtime.Now(),
	})
	return
}
